/************************************************************************/
/*    Author: Scott Bevin									            */
/************************************************************************/

#pragma once

#include <map>
#include <string>

#include "Property.h"
#include "../XUtilities/Logger.h"
#include "PropertyFactory.h"

namespace XF
{
	class PropertyContainer
	{
	protected:
		std::map<std::string, IProperty*> mProperties;

	public:
		PropertyContainer();
		PropertyContainer(PropertyContainer &copy);
		virtual ~PropertyContainer();

		bool HasProperty(std::string propName)
		{
			return (mProperties.find(propName) != mProperties.end());
		}
		int NumOfProperties()
		{
			return mProperties.size();
		}
		
		void AddProperty(IProperty *prop);

		template<class T>
		void AddProperty(const std::string &name, T value)
		{
			AddProperty(PropertyFactory::CreatePropertyUsingType<T>(name, value));
		}

		template<class T>
		Prop<T>& Property(const std::string &name);
		
		IProperty *GetIProperty(const std::string &name);

		void RemoveProperty(const std::string &name);
		void RemoveAllProperties();

		typedef std::map<std::string, IProperty*>::iterator PropertyIT; //chris i added this
		std::map<std::string, IProperty*> *Properties(){return &mProperties;}
	};
	
	template<class T>
	Prop<T>& PropertyContainer::Property(const std::string &name)
	{
		std::map<std::string, IProperty*>::iterator it = mProperties.find(name);

		if(it != mProperties.end())
		{
			Prop<T>* prop = dynamic_cast< Prop<T>* >(it->second);

			assert(prop);

			return *prop;
		}
		else
		{
			AddProperty(PropertyFactory::CreatePropertyUsingType<T>(name));
			return Property<T>(name);
		}
	}
}

